package com.thinvent.recommend.manager.manager.impl;

import com.thinvent.recommend.entity.KbFileInfo;
import com.thinvent.recommend.manager.dto.KbFileContentDTO;
import com.thinvent.recommend.manager.dto.Pager;
import com.thinvent.recommend.manager.manager.FileInfoManager;
import com.thinvent.recommend.manager.manager.Text2VecHelperManager;
import com.thinvent.recommend.manager.manager.Text2VecManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * TF–IDF 全量向量化 + 批量 upsert 到 ES（区分创建与更新时间）
 * <p>支持按时间区间增量或全量同步。</p>
 */
@Component
public class Text2VecManagerImpl implements Text2VecManager {

    private final FileInfoManager fileInfoManager;
    private final Text2VecHelperManager helperManager;

    @Autowired
    public Text2VecManagerImpl(FileInfoManager fileInfoManager,
                               Text2VecHelperManager helperManager) {
        this.fileInfoManager = fileInfoManager;
        this.helperManager   = helperManager;
    }

    /**
     * 全量或按时间区间增量同步。
     *
     * @param startTime 可选；只同步 updateTime >= startTime
     * @param endTime   可选；只同步 updateTime <= endTime
     */
    @Override
    public void processFileInfoPages(LocalDateTime startTime, LocalDateTime endTime) {
        final int pageSize = 20;
        int page = 1;

        while (true) {
            // 1. 从数据库分页拉取真实存在的文件列表
            Pager<KbFileInfo> pager = fileInfoManager.listActiveFiles(
                    page, pageSize, startTime, endTime
            );
            List<KbFileInfo> infos = pager.getData();
            if (infos == null || infos.isEmpty()) {
                break;
            }

            // 2. 解析 & 向量化内容
            List<KbFileContentDTO> docs = helperManager.fetchAndParse(infos);
            if (docs.isEmpty()) {
                page++;
                continue;
            }

            Map<String, Map<String, Double>> vectors =
                    helperManager.computeTfIdf(docs);
            if (vectors.isEmpty()) {
                page++;
                continue;
            }

            // 3. 仅保留本次从 DB 拉取的 ID 对应的向量
            Set<String> validIds = infos.stream()
                    .map(KbFileInfo::getId)
                    .collect(Collectors.toSet());
            Map<String, Map<String, Double>> filtered = vectors.entrySet().stream()
                    .filter(e -> validIds.contains(e.getKey()))
                    .collect(Collectors.toMap(
                            Map.Entry::getKey,
                            Map.Entry::getValue
                    ));

            // 4. 如果有合法向量，则批量 upsert 到 ES
            if (!filtered.isEmpty()) {
                helperManager.upsertToElasticsearch(filtered);
            }

            page++;
        }
    }
}
